###############################################################################
###############################################################################
#                               ANALYSIS SCRIPT                               #
#TOE THE LINE TO SURVIVE: LOYALISTS, WILDCARDS, AND ELECTORAL REFORM IN BRAZIL#
#                     MATHEUS CUNHA & CARLOS PEREIRA                          #
###############################################################################
###############################################################################

# This is a submission script. Should you find any issues with it, please reach 
# out to the corresponding author (Matheus) at: matheus.cunha@ufpe.br

# Necessary packages

packages <- c("tidyverse", "lubridate", "stringr", "fixest", "modelsummary", "ggsci")

installed_packages <- packages %in% rownames(installed.packages())
if (any(installed_packages == FALSE)) {
  install.packages(packages[!installed_packages], repos = 'http://cran.us.r-project.org')
  if("tinytex" %in% packages[!installed_packages])
    tinytex::install_tinytex()
}

invisible(lapply(packages, library, character.only = TRUE))

# Load the data

d2 <- read_csv("wildcards.csv")

# Create placebo dataset 

d2_placebo <- d2 %>% 
  filter(ano_trimestre < 2017.4) %>% 
  mutate(postreform = ifelse(ano_trimestre > 2015.3, 1, 0), 
         reforma = wildcard * postreform)

# calculate loyalty before and after the reform

simpleavg <- d2 %>% 
  mutate(wildcard = as.character(wildcard)) %>% 
  mutate(dates = paste0(ano, ifelse(semestre == 1, "-01-01", "-07-07"))) %>% 
  mutate(ano_semestre = as.Date(dates)) %>%  
  group_by(ano_semestre, wildcard) %>% 
  summarize(fidelidade = mean(fidelidade, na.rm = T)) %>% 
  filter(!is.na(wildcard))

simpleavg$time <- c(-5, -5, -4, -4, -3, -3, -2, -2, -1, -1, 0, 0, 1, 1, 2, 2, 3, 3, 
                    4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 
                    13, 13)

teste2 <- d2 %>% 
  mutate(dates = paste0(ano, ifelse(semestre == 1, "-01-01", "-07-07"))) %>% 
  group_by(dates, ano_semestre) %>% summarise(avg = mean(fidelidade, na.rm = T))
teste2 <- teste2 %>% mutate(postreform = if_else(ano_semestre > 2017.1, 1, 0))
beforeafter <- teste2 %>% group_by(postreform) %>% summarise(fidel = mean(avg, na.rm = T))

teste2$time <- c(-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)

fidelidadeplot <- teste2 %>% 
  ggplot(aes(time, avg)) + 
  geom_line() +
  geom_point() + 
  geom_vline(xintercept = 0, linetype = "dashed") +
  geom_segment(x = -5, xend = 0, 
               y = 81.4, yend = 81.4, linetype = "twodash", color = "darkred") + 
  geom_segment(x = 0, xend = 13, 
               y = 84.7, yend = 84.7, linetype = "dotted", color = "dodgerblue") + 
  theme_minimal() + 
  scale_x_continuous(breaks = c(-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
                                11, 12, 13), 
                     labels = c("2015.1", "2015.2", "2016.1", "2016.2", "2017.1",
                                "2017.2","2018.1", "2018.2", "2019.1", "2019.2", 
                                "2020.2", "2021.1", "2021.2", "2022.1",
                                "2022.2", "2023.1", "2023.2", "2024.1", "2024.2")) + 
  theme(axis.text.x = element_text(angle = 45, vjust = 0.7)) +
  labs(x = NULL, y = "Partisan Loyalty", title = "(A)") + 
  ggsci::scale_color_npg() + 
  plot_theme

paralelas <- simpleavg %>%
  ggplot(aes(time, fidelidade, color = wildcard)) + 
  geom_line() + 
  geom_point() + 
  geom_vline(xintercept = 0, linetype = "dashed") +
  scale_x_continuous(breaks = c(-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
                                11, 12, 13), 
                     labels = c("2015.1", "2015.2", "2016.1", "2016.2", "2017.1",
                                "2017.2","2018.1", "2018.2", "2019.1", "2019.2", 
                                "2020.2", "2021.1", "2021.2", "2022.1",
                                "2022.2", "2023.1", "2023.2", "2024.1", "2024.2")) +
  labs(x = NULL, y = NULL, title = "(B)") +
  theme(axis.text.x = element_text(angle = 45, vjust = 0.7), 
        legend.position = "top") +
  ggsci::scale_color_npg() + 
  plot_theme

# put the plots together and store

fidelidade <- ggpubr::ggarrange(fidelidadeplot, paralelas, ncol = 2)

ggsave("fidelidade.png", fidelidade, dpi = 600, height = 16, width = 20, units = "cm")

# Compute average levels of loyalty, before and after the reform

averages <- d2 %>% 
  filter(!is.na(wildcard)) %>% 
  mutate(wildcard = as.factor(wildcard), 
         postreform = as.factor(postreform)) %>% 
  group_by(wildcard, postreform) %>% 
  summarise(avg = mean(fidelidade, na.rm = T))

avgchanges <- averages %>% 
  mutate(wildcard = as.factor(wildcard)) %>% 
  ggplot(aes(postreform, avg, fill = wildcard)) + 
  geom_bar(stat = "identity", position = "dodge") + 
  labs(x = NULL, y = "Partisan Loyalty") + 
  scale_x_discrete(labels = c("Before", "After")) + 
  ggsci::scale_fill_lancet() +
  plot_theme

ggsave("avgchanges.png", avgchanges, dpi = 600, height = 16, width = 18, units = "cm")

# Main effects + placebo

m1a <- feols(fidelidade ~ reforma | deputado_.id + ano_semestre, 
             data = d2, cluster = ~deputado_.id)
m1b <- feols(fidelidade ~ reforma | deputado_.id + ano_semestre + deputado_siglaPartido, 
             data = d2, cluster = ~deputado_.id) 
m1c <- feols(fidelidade ~ reforma | deputado_.id + ano_semestre, 
             data = d2_placebo, cluster = ~deputado_.id)
m1d <- feols(fidelidade ~ reforma + prob_same_party + base_governo + carreira + 
               genero | deputado_.id + ano_semestre, 
             data = d2, cluster = ~deputado_.id)

m1e <- feols(fidelidade ~ reforma * prob_same_party| deputado_.id + ano_semestre, 
             data = d2, cluster = ~deputado_.id)

m1f <- feols(prob_same_party ~ reforma | deputado_.id + ano_semestre, 
             data = d2, cluster = ~deputado_.id)

main <- list(m1a, m1b, m1c, m1d) # main effects

msummary(main, stars = c("*" = .05, "**" = .01, "***" = .001), 
         statistic = "conf.int") 

partyfrag <- list(m1e, m1f) # suggestive mediation + moderation

msummary(partyfrag, stars = c("*" = .05, "**" = .01, "***" = .001), 
         statistic = "conf.int")

# Test reform effects on the probability of belonging to parties of different size

d3 <- d2 %>% 
  mutate(ano_semestre = as.factor(ano_semestre))

party_size <- d3 %>%
  group_by(ano_semestre, deputado_siglaPartido) %>%
  summarise(avg_size = mean(prob_same_party, na.rm = TRUE), .groups = "drop")

party_stats <- party_size %>%
  group_by(ano_semestre) %>%
  summarise(mean_size = mean(avg_size, na.rm = TRUE),
            sd_size = sd(avg_size, na.rm = TRUE), .groups = "drop")

party_classification <- party_size %>%
  left_join(party_stats, by = "ano_semestre") %>%
  mutate(party_size_category = case_when(
    avg_size < (mean_size - sd_size) ~ "small",
    avg_size > (mean_size + sd_size) ~ "big",
    TRUE ~ "medium"
  )) %>%
  select(ano_semestre, deputado_siglaPartido, party_size_category)

d3 <- d3 %>%
  left_join(party_classification, by = c("ano_semestre", "deputado_siglaPartido")) 

d3 <- d3 %>% 
  mutate(
    big = if_else(party_size_category == "big", 1, 0), 
    medium = if_else(party_size_category == "medium", 1, 0), 
    small = if_else(party_size_category == "small", 1, 0)
  )

m8a <- feols(big ~ reforma | deputado_.id + ano_semestre, 
             data = d3, cluster = ~deputado_.id)

m8b <- feols(medium ~ reforma | deputado_.id + ano_semestre, 
             data = d3, cluster = ~deputado_.id)

m8c <- feols(small ~ reforma | deputado_.id + ano_semestre, 
             data = d3, cluster = ~deputado_.id)

sizes <- list(m1f, m8a, m8b, m8c)

msummary(sizes, stars = c("*" = .05, "**" = .01, "***" = .001), 
         statistic = "conf.int")

m9a <- feols(fidelidade ~ prob_same_party | deputado_.id + ano_semestre, 
             data = d2, cluster = ~deputado_.id) # correlation between party size and loyalty

msummary(m9a, stars = c("*" = .05, "**" = .01, "***" = .001), 
         statistic = "conf.int")

sizeloyalty <- d3 %>% 
  group_by(party_size_category, postreform) %>% 
  summarise(avg_fidel = mean(fidelidade, na.rm = TRUE), .groups = "drop")

sizeloyalplot <- sizeloyalty %>% 
  ggplot(aes(x = factor(postreform), y = avg_fidel, fill = party_size_category)) + 
  geom_bar(stat = "identity", position = "dodge") + 
  labs(x = NULL, y = "Partisan Loyalty", fill = "Party Type") + 
  scale_x_discrete(labels = c("Before", "After")) +
  ggsci::scale_fill_npg() +
  plot_theme # Loyalty per party size

ggsave("newsizes.png", sizeloyalplot, dpi = 600, height = 16, width = 18, units = "cm")

# marginal effects 

mfx <- marginaleffects::slopes(
  model = m1e,
  variables = "reforma",
  newdata = marginaleffects::datagrid(prob_same_party = seq(0.2, 22.3, by = 0.01))
) # marginal effect of the reform per party size

interaction <- ggplot(mfx, aes(x = prob_same_party, y = estimate)) +
  geom_line(size = 1) +
  geom_ribbon(aes(ymin = conf.low, ymax = conf.high), alpha = 0.2) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +
  labs(
    x = "Party Size (% of chairs)",
    y = "Marg. Eff. Party Loyalty (%)",
    title = NULL
  ) +
  plot_theme

ggsave("interaction.png", interaction, dpi = 600, height = 16, width = 18, units = "cm")

# Main effects (no placebo) for different wildcard specifications

m3a <- feols(fidelidade ~ reforma| deputado_.id + ano_semestre, 
             data = d2, cluster = ~deputado_.id)

m3b <- feols(fidelidade ~ reforma2 | deputado_.id + ano_semestre, 
             data = d2, cluster = ~deputado_.id)

m3c <- feols(fidelidade ~ reforma3 | deputado_.id + ano_semestre, 
             data = d2, cluster = ~deputado_.id)

m3d <- feols(fidelidade ~ reforma4 | deputado_.id + ano_semestre, 
             data = d2, cluster = ~deputado_.id)

multiples <- list(m3a, m3b, m3c, m3d)

msummary(multiples, stars = c("*" = .05, "**" = .01, "***" = .001), 
         statistic = "conf.int")

# main effects across coalition status

m6a <- feols(fidelidade ~ reforma * base_governo | deputado_.id + ano_semestre, 
             data = d2, cluster = ~deputado_.id)

msummary(m6a, stars = c("*" = .05, "**" = .01, "***" = .001), 
         statistic = "conf.int")

# dynamic model for main effects 

m2a <- feols(fidelidade ~ i(treatment_center, wildcard, ref = 0) | 
               deputado_.id + ano_semestre + deputado_siglaPartido, 
             data = d2, cluster = ~deputado_.id) # atenção na mensuração de wildcard escolhida!!

msummary(m2a, stars = c("*" = .05, "**" = .01, "***" = .001), 
         statistic = "conf.int")

# plot for dynamic effects 

m2acoef <- coef(m2a)
m2aconf <- confint(m2a)
m2aout <- cbind(m2acoef, m2aconf)

m2aout <- m2aout %>% rename(
  estimate = m2acoef, 
  lower = `2.5 %`, 
  upper = `97.5 %`
)

m2aout$time <- c(-4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
m2aout$treatment <- "reforma"
m2aout$president <- c("Dilma Rousseff", "Dilma Rousseff", "Dilma Rousseff", 
                      "Michel Temer", "Michel Temer", "Michel Temer", "Michel Temer", 
                      "Jair Bolsonaro", "Jair Bolsonaro", "Jair Bolsonaro", "Jair Bolsonaro", 
                      "Jair Bolsonaro", "Jair Bolsonaro", "Jair Bolsonaro", 
                      "Lula", "Lula", "Lula", "Lula")

presidentorder <- c("Dilma Rousseff", "Michel Temer", "Jair Bolsonaro", "Lula")

labels <- c("2015.1", "2015.2", "2016.1", "2016.2", "2017.2", 
            "2018.1", "2018.2", "2019.1", "2019.2", 
            "2020.2", "2021.1", "2021.2", "2022.1", "2022.2", 
            "2023.1", "2023.2", "2024.1", "2024.2")


dynamicplot <- m2aout %>% 
  mutate(president = factor(president, levels = presidentorder)) %>% 
  ggplot(aes(time, estimate, color = president)) + 
  geom_point(size = 2, shape = 20) +
  geom_vline(xintercept = 0, linetype = "dashed") + 
  geom_errorbar(aes(ymin = lower, ymax = upper), width = 0.2) + 
  geom_hline(yintercept = 0, linetype = "solid") +
  theme_minimal() + 
  labs(x = NULL, y = "Estimate (95% Confidence Intervals)") + 
  plot_theme +
  scale_x_continuous(breaks = c(-4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
                                12, 13, 14), labels = labels) +
  theme(axis.text.x = element_text(angle = 45, vjust = 1.2, hjust = 1), 
        legend.position = "top") +
  ggsci::scale_color_npg()

ggsave("dynamic.png", dynamicplot, dpi = 600, width = 22, height = 16, units = "cm")

# Distribution of wildcards and loyalists across party sizes, before and after the reform

totals <- d2 %>% 
  group_by(wildcard, postreform) %>% 
  summarise(totals = n()) %>% 
  filter(!is.na(wildcard))

one <- d2 %>% 
  filter(!is.na(prob_same_party)) %>% 
  group_by(postreform) %>% 
  mutate(meansize = mean(prob_same_party, na.rm = T), 
         sdsize = sd(prob_same_party, na.rm = T), 
         smallparty = meansize - sdsize, 
         bigparty = meansize + sdsize) %>% 
  ungroup() %>% 
  group_by(deputado_.id, postreform) %>% 
  mutate(littleguy = ifelse(prob_same_party <= smallparty, 1, 0), 
         bigguy = ifelse(prob_same_party >= bigparty,1,0), 
         avgguy = ifelse(prob_same_party > smallparty & prob_same_party < bigparty, 1,  0)) %>% 
  ungroup() %>% 
  mutate(count = n()) %>% 
  select(deputado_.id, postreform, wildcard, ano, littleguy, 
         bigguy, avgguy, count, deputado_siglaPartido)

little <- one %>% group_by(wildcard, postreform) %>% 
  summarize(small = sum(littleguy, na.rm = T)) %>% 
  filter(!is.na(wildcard))
little$total <- c(531, 1612,82,232)
little <- little %>% group_by(wildcard, postreform) %>% 
  mutate(prct = (small / total) * 100) %>% 
  select(wildcard, postreform, prct)

avg <- one %>% group_by(wildcard, postreform) %>% 
  summarise(medium = sum(avgguy, na.rm = T)) %>% 
  filter(!is.na(wildcard))
avg$total <- c(531, 1612,82,232)
avg <- avg %>% group_by(wildcard, postreform) %>% 
  mutate(prct = (medium / total) * 100) %>% 
  select(wildcard, postreform, prct)

big <- one %>% group_by(wildcard, postreform) %>% 
  summarize(big = sum(bigguy, na.rm = T)) %>% 
  filter(!is.na(wildcard))
big$total <- c(531, 1612,82,232)
big <- big %>% group_by(wildcard, postreform) %>% 
  mutate(prct = (big / total) * 100) %>% 
  select(wildcard, postreform, prct)

all <- rbind(little, avg, big)
all$size <- c("small", "small", "small", "small", 
              "medium", "medium", "medium", "medium", 
              "big", "big", "big", "big")
all <- all %>% mutate(wildcard = as.factor(wildcard), 
                      postreform = as.factor(postreform))

partyorder <- c("small", "medium", "big")

partyplot <- all %>% mutate(size = factor(size, levels = partyorder)) %>% 
  ggplot(aes(wildcard, prct, fill = size)) + 
  geom_bar(stat = "identity", position = "dodge") +
  facet_wrap(~postreform, labeller = labeller(postreform = c("0" = "Before", 
                                                             "1" = "After"))) +
  theme_minimal() + 
  labs(x = NULL, y = "Incidence", fill = "Party Size") + 
  scale_x_discrete(labels = c("Loyalists", "Wildcards", "Loyalists", "Wildcards")) +
  scale_y_continuous(breaks = c(0, 10, 20, 30, 40,  50, 60, 70, 80, 90)) +
  ggsci::scale_fill_npg() + 
  plot_theme

ggsave("partyplot2.png", partyplot, dpi = 600, width = 22, height = 16, units = "cm")


# Mechanisms (pork, campaign financing, offices)


m4a <- feols(emendas ~ reforma | 
               deputado_.id + ano_semestre, 
             data = d2)

m4b <- feols(campanha ~ reforma | 
               deputado_.id + ano_semestre, 
             data = d2)

m4c <- feols(cargo_mesas ~ reforma | 
               deputado_.id + ano_semestre, 
             data = d2)

mecanismos <- list(m4a, m4b, m4c)

msummary(mecanismos, stars = c("*" = .05, "**" = .01, "***" = .001), 
         statistic = "conf.int", output = "mecanismos-table.tex")

##### PLOTS ##### 

# main effects + controls + placebo 

modelsrealmain <- list(
  "No controls" = m1a, 
  "Party FEs" = m1b, 
  "Placebo" = m1c, 
  "With Controls" = m1d 
)

tidy_models <- purrr::map_df(
  modelsrealmain, 
  ~tidy(.x, conf.int = T), 
  .id = "model"
)

tidy_models_filtered <- tidy_models %>% 
  filter(term == "reforma") %>% 
  mutate(
    model = fct_rev(factor(model, levels = c("No controls", "Party FEs", 
                                             "Placebo", "With Controls")))
  )

maineffs <- ggplot(tidy_models_filtered, aes(x = estimate, y = model, color = model)) +
  geom_vline(xintercept = 0, linetype = "dashed", color = "black") +
  geom_point(position = position_dodge(width = 0.7), size = 2.5) +
  geom_errorbar(aes(xmin = conf.low, xmax = conf.high),
                position = position_dodge(width = 0.7),
                width = 0.2) +
  labs(
    x = "Est. Loyalty Increase (%)",
    y = NULL,
    title = NULL,
    color = "Model"
  ) +
  scale_x_continuous(breaks = c(0, 5, 10, 15, 20, 25, 30)) +
  plot_theme +
  ggsci::scale_color_lancet() + 
  theme(legend.position = "none")

ggsave("maineffs.png", maineffs, dpi = 600, height = 16, width = 18, units = "cm")

# effects for governing coalition and opposition

marginal_effects <- emmeans::emmeans(m6a, ~ reforma | base_governo)

reforma_slopes <- emmeans::contrast(marginal_effects, 
                                    method = "revpairwise", reverse = TRUE)
reforma_df <- as.data.frame(reforma_slopes)

reforma_slopes_ci <- confint(reforma_slopes)

reforma_df <- as.data.frame(reforma_slopes_ci) %>%
  mutate(
    base_governo = c("Opposition", "Gov. Coalition"), 
    estimate = estimate,
    lower = lower.CL,
    upper = upper.CL
  )

coalbaseplot <- ggplot(reforma_df, aes(x = base_governo, y = estimate, color = base_governo)) +
  geom_point(size = 2) +
  geom_errorbar(aes(ymin = lower, ymax = upper), width = 0.1) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +
  labs(
    x = NULL,
    y = "Marginal Effects (% Loyalty)",
    title = NULL
  ) +
  plot_theme + 
  ggsci::scale_colour_lancet() + 
  theme(legend.position = "none")

ggsave("coalbase.png", coalbaseplot, dpi = 600, height = 16, width = 18, units = "cm")

# mechanisms - money 

modelsmoney <- list(
  "Pork" = m4a, 
  "Campaign funds" = m4b
)

tidy_models <- map_df(
  modelsmoney, 
  ~tidy(.x, conf.int = T), 
  .id = "model"
)

tidy_models_filtered <- tidy_models %>% 
  filter(term %in% "reforma") %>% 
  mutate(
    model = factor(model, levels = c("Pork (1000x)", "Campaign funds (1000x)"))
  )

moneyplot <- ggplot(tidy_models_filtered, aes(x = estimate, y = model, color = model)) +
  geom_vline(xintercept = 0, linetype = "dashed", color = "black") +
  geom_point(position = position_dodge(width = 0.7), size = 2.5) +
  geom_errorbar(aes(xmin = conf.low, xmax = conf.high),
                position = position_dodge(width = 0.7),
                width = 0.2) +
  labs(
    x = "Est. Effs. (1K reais)",
    y = NULL,
    title = NULL,
    color = "Model"
  ) +
  scale_x_continuous(breaks = c(-2000,-1500, -1000, -500, 0 , 
                                500, 1000, 1500, 2000, 3000)) +
  plot_theme +
  ggsci::scale_color_lancet() + 
  theme(legend.position = "none", 
        axis.text.x = element_text(angle = 45, hjust = 1))

ggsave("money.png", moneyplot, dpi = 600, height = 16, width = 18, units = "cm")

# mechanisms - offices 

modelsjobs <- list(
  "Mesa Diretora" = m4c, 
  "Frentes Parlamentares" = m4d
)

# multiple wildcard definitions 

modelsmain <- list(
  "< Loyal. party" = m3a,
  "< Loyal. party lag" = m3b,
  "< 1sd congress" = m3c,
  "< Median congress" = m3d
)

tidy_models <- purrr::map_dfr(
  modelsmain,
  ~tidy(.x, conf.int = TRUE),
  .id = "model"
)

tidy_models_filtered <- tidy_models %>%
  filter(term %in% c("reforma", "reforma2", "reforma3", "reforma4")) %>%
  mutate(
    term = factor(term, levels = rev(c("reforma", "reforma2", "reforma3", "reforma4"))),
    model = factor(model, levels = c("< Loyal. party", "< Loyal. party lag", 
                                     "< 1sd congress", "< Median congress"))
  )

manywilds <- ggplot(tidy_models_filtered, aes(x = estimate, y = term, color = model)) +
  geom_vline(xintercept = 0, linetype = "dashed", color = "black") +
  geom_point(position = position_dodge(width = 0.7), size = 2.5) +
  geom_errorbar(aes(xmin = conf.low, xmax = conf.high),
                position = position_dodge(width = 0.7),
                width = 0.2) +
  labs(
    x = "Est. Loyalty Increase (%)",
    y = NULL,
    title = NULL,
    color = "Model"
  ) +
  scale_x_continuous(breaks = c(0, 5, 10, 15, 20, 25, 30)) +
  plot_theme +
  ggsci::scale_color_lancet() + 
  theme(legend.position = "top")

ggsave("manywilds.png", manywilds, dpi = 600, height = 16, width = 18, 
       units = "cm")

#### CHECKING FOR PARALLEL TRENDS AGAIN ##### 

pretreat <- d2 %>% filter(ano_semestre < 2017.2) %>% 
  mutate(newtime = case_when(
    ano_semestre == "2015.1"~ 1, 
    ano_semestre == "2015.2" ~ 2, 
    ano_semestre == "2016.1" ~ 3, 
    ano_semestre == "2016.2" ~ 4, 
    ano_semestre == "2017.1" ~ 5
  )) %>% 
  mutate(newtime = as.factor(newtime))

pretreat <- d2 %>% 
  filter(ano_semestre < 2017.2) %>% 
  mutate(time_counter = as.numeric(factor(ano_semestre)))

m7a <- feols(fidelidade ~ wildcard * time_counter | deputado_.id + ano_semestre + 
               deputado_siglaPartido, 
             data = pretreat, cluster = ~deputado_.id)

msummary(m7a, stars = c("*" = .05, "**" = .01, "***" = .001), 
         statistic = "conf.int") 

################################################################################